/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package uk.ac.cam.ccn.sac.modules.audio.streaming;

import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import org.ccnx.ccn.CCNHandle;
import org.ccnx.ccn.config.ConfigurationException;
import org.ccnx.ccn.io.CCNInputStream;
import org.ccnx.ccn.io.CCNOutputStream;
import org.ccnx.ccn.protocol.ContentName;
import org.ccnx.ccn.protocol.MalformedContentNameStringException;
import uk.ac.cam.ccn.sac.modules.audio.CaptureThread;
import uk.ac.cam.ccn.sac.modules.audio.PlayThread;
import uk.ac.cam.ccn.sac.modules.contacts.Contact;

/**
 *
 * @author Thomas
 */
public class AudioStreamsManager {
    private static final AudioStreamsManager instance = new AudioStreamsManager();
    private Map<String, PlayThread> players = new HashMap<String, PlayThread>();
    
    private AudioStreamsManager(){}
    
    public static AudioStreamsManager getInstance(){
        return instance;
    }
    
    public void subAudioStream(Contact contact) throws IOException, MalformedContentNameStringException{
        String username = contact.getAttribute(Contact.USER_NAME);
        String stream = contact.getAttribute(Contact.AUDIO_STREAM);
        if(stream==null)
            return; //there is no such audio stream attribute we exit
        if(!players.containsKey(username)){
            PlayThread t = startPlayerThread(stream);
            if(t!=null)
                players.put(username, t);
        }else{
            System.out.println("There is already a registered player thread");
            PlayThread t = players.get(username);
            if(!t.isAlive()){
                System.out.println("The thread has died");
                t = startPlayerThread(stream);
                if(t!=null){
                    players.remove(username);
                    players.put(username, t);
                }
            }
        }
    }
    
    public void unsubAudioStream(Contact contact){
        String username = contact.getAttribute(Contact.USER_NAME);
        if(players.containsKey(username)){
            System.out.println("Find a reader for this contact");
            PlayThread t = players.get(username);
            t.stopPlay(); // we ask the thread to stop
            players.remove(username);  // we remove it from the list of threads
        }
    }
    
    private PlayThread startPlayerThread(String stream) throws IOException, MalformedContentNameStringException{
        PlayThread pt=null;
        InputStream input=new CCNInputStream(ContentName.fromURI(stream));
        pt= new PlayThread(input);
        pt.start();
        return pt;
    }
    
    public void pubAudioStream(Contact localContact) throws ConfigurationException, IOException, MalformedContentNameStringException{
        // we launch the audio streaming
        CCNHandle audioStreamHandle = CCNHandle.open();
        ContentName audioStreamNameSpace = ContentName.fromURI(localContact.getAttribute(Contact.AUDIO_STREAM));
        CCNOutputStream out = new CCNOutputStream(audioStreamNameSpace, audioStreamHandle);
        // according to doc should be flushed after 128 block
        // we set the block size that it last around 1s
        out.setBlockSize(80);
        // this thread write the captured audio to the OutputStream
        Thread t1 = new CaptureThread(out);
        t1.start();
    }
}
